#include "Troll3D/Application.h"


	/****************************************/
	/*				Static					*/
	/****************************************/

        /****************************************
        /*				Properties
		/****************************************/
		         
            int                 Application::s_Run;

            float               Application::s_TimeLastFrame;   /*!< Time, in ms, where the last frame has been refreshed       */
            float               Application::s_Delta;           /*!< Time, in ms, between each Frame, defined by s_Framerate    */
            float               Application::s_Framerate;       /*!< Frame per second                                           */


            Clock               Application::s_Clock;
            SFMLWindow *        Application::s_Window;          /*!< Window linked to the application                           */
            sf::Event           Application::s_CurrentEvent;    /*!< Store current Event 						*/

			
        /****************************************
        /*				Methods
		/****************************************/		
				

            void Application::Init()
            {
                s_Clock.Start();
                InitializeGL();
            }

            void Application::InitializeGL()
            {
                glewInit();

                BufferObject::InitBuffers();
                glDisable(GL_CULL_FACE);

                glClearDepth(1.f);
                glClearColor(0.5f, 0.5f, 0.5f, 1.0f);

                // Enable Z-buffer read and write

                glEnable(GL_DEPTH_TEST);
                glDepthMask(GL_TRUE);
            }

            SFMLWindow * Application::SetWindow(int width, int height, int framerate)
            {
                s_Window = new SFMLWindow(width, height);
                s_Framerate = framerate;

                s_Delta = (1.0/ framerate);
                s_Delta = s_Delta*1000;
                s_TimeLastFrame=0;
                s_Run       =   true;
            }
			
			void Application::EventManagement(sf::Event event)
			{
				switch(event.type)
				{
					case sf::Event::Closed :

                        s_Run=0;

					break;
				}
			}

			void Application::UpdateEntities()
			{
                View::MainView->Update();
				for(int i=0;i<Entity::Entities.size(); i++)
				{
					Entity::Entities[i]->Update();
				}
			}

			void Application::UpdateDisplay()
            {
				glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
				
				BufferObject::BindVBO();
				BufferObject::BindIBO();
				
                for(int i=0; i<Entity::Entities.size();i++)
				{
                    Entity::Entities[i]->Display();
				}
			}

			void Application::Loop()
            {
                while(s_Run)
				{
                    if( (s_Clock.TimeElapsed()- s_TimeLastFrame)> s_Delta  )
                    {
                        s_TimeLastFrame=s_Clock.TimeElapsed();

                        while(s_Window->m_Window->pollEvent(s_CurrentEvent))
                        {
                            EventManagement(s_CurrentEvent);
                            UpdateEntities();
                        }

                        UpdateDisplay();

                        s_Window->m_Window->display();
                    }
                    else
                    {
                        Sleep( s_Delta-(s_Clock.TimeElapsed()-s_TimeLastFrame));
                    }
				}
			}
			
    /****************************************
    /*				Constructors
	/****************************************/	
			
		Application::Application()
		{
		
			
		}
